import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import java.util.Observable;
import java.util.Observer;

import javax.swing.Timer;


/*
 * ****************************
 * Eric Doherty
 * Jesse Kinney
 * 
 * TCSS 422 Scheduler simulator
 * I/O Class
 * 
 * 6/4/08
 * ****************************
 */

public class IO extends Observable implements Observer
{
  private static int nextID = 0;

  private int id;

  private LinkedList<Process> waitingQueue;

  private Timer timer;

  public IO()
  {
    this.id = nextID++;
    waitingQueue = new LinkedList<Process>();
  }

  public void serviceIO()
  {
    timer = new Timer((int) (Math.random() * 9 + 1), new ActionListener()
    {
      public void actionPerformed(ActionEvent evt)
      {
        Process finishedIO = waitingQueue.poll();

        setChanged();
        System.out.println("IO finished for process " + finishedIO.getPid()
            + ", sending interrupt");

        if (id == 0)
        {
          notifyObservers(new Event(Event.EventTypes.UNBLOCKIO1,
              new Interrupt(1, Event.EventTypes.UNBLOCKIO1)));
        }
        else
        {
          notifyObservers(new Event(Event.EventTypes.UNBLOCKIO2,
              new Interrupt(1, Event.EventTypes.UNBLOCKIO2)));
        }
      }
    });

    timer.setRepeats(false);
    timer.start();
  }

  public void update(Observable o, Object obj)
  {

    if (obj != null)
    {
      {
        Event event = (Event) obj;
        if (event.getType() == Event.EventTypes.STARTIO1 && id == 0)
        {
          waitingQueue.offer((Process) o);
          serviceIO();
        }
        else if (event.getType() == Event.EventTypes.STARTIO2 && id == 1)
        {
          waitingQueue.offer((Process) o);
          serviceIO();
        }
      }
    }
  }

  public Timer getTimer()
  {
    return timer;
  }
}
